<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
    <div id="app">
        <!--
            这里的自定义事件myclick被触发后会调用myFunc方法（父组件中定义暴露的方法）
        -->
        <my-alert title="自定义标题1" @myclick="myFunc"></my-alert>
        <my-alert title="自定义标题2" @myclick="myFunc"></my-alert>
    </div>
<script>
  const {createApp} = Vue
  const app = createApp({
    setup() {
      // 父组件中的方法
      // 这里的参数用来接收子组件传递的参数
      const myFunc = (params) => {
        // if (params === undefined) {
        //   alert("父组件中的方法")
        // } else {
        //   alert("父组件中的方法：" + params)
        // }
        alert(params === undefined ? "父组件中的方法" : "父组件中的方法：" + params)
      }
      return {myFunc}
    }
  })
  const alertComponent = {
    // 声明外部属性
    props:["title"],
    /*
      这里点击时使用$emit()方法，将自定义事件myclick发送给父组件
      $emit()方法接收两个参数：
          第一个参数是自定义事件名称
          第二个参数是自定义事件发送的数据
      如果我们在触发事件前有一些内部逻辑要处理，可以在子组件中定义一个方法，然后在这个方法内部调用emit进行事件传递
      注意：如果在setup方法中调用emit事件，需要显式地把事件声明出来
      好的开发模式是：
          组件内部的逻辑在组件内部处理掉，而需要调用方处理的业务逻辑属于组件外部的逻辑，可以把它传递到调用方处理。
     */
    // template: `<div><button @click="$emit('myclick',title)">{{title}}</button></div>`
    template: `<div><button @click="innerClick">{{title}}</button></div>`,
    emits: ['myclick'], // 把组件事件显式声明出来
    setup(props,ctx) {
      const innerClick = () => {
        // 组件内部的逻辑
        console.log("组件内部点击了")
        // 使用ctx参数可以调用emit方法来触发组件事件
        ctx.emit('myclick',props.title)
      }

      return {innerClick}
    }
  }
  app.component("my-alert",alertComponent)
  app.mount("#app")

</script>
</body>
</html>